/*
  Copyright 2011 Tobias "Tomoko" Platen

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "sekai/VoiceSampler.h"

// FIXME: do not hardcode
#define factor 4
#define delay 0
#include <sndfile.h>
#include <boost/filesystem.hpp>

VoiceSampler::VoiceSampler(int buffer_size) : OLABuffer(buffer_size) {}

VoiceSampler::~VoiceSampler() {}

bool VoiceSampler::readData(float* data, int size, int fill) {
  // TODO: fill if no data
  while (!isFilled(fill)) {
    if (addOnePulse() == false) return false;
  }

  pop(data, size);
  postProcess(data,size);
  outputPos+=size;
  return true;
}

#if 0
int VoiceSampler::findPitchMark(struct Track& track, float pos,
                                struct Pitch& p0, struct Pitch& p1,
                                float* out) {
  int count = track.getPitchCount();
  for (int i = 0; i < count - 1; i++) {
    p0 = track.getPitch(i);
    p1 = track.getPitch(i + 1);
    if (p0.pos <= pos && p1.pos > pos) {
      if (out) *out = (pos - p0.pos) / (p1.pos - p0.pos);
      return i;
    }
  }
  return -1;
}
#endif

#if 0
bool VoiceSampler::load(struct VoiceRecord& record, int& samplerate,
                        std::string fileName) {
  std::string f0 =
      boost::filesystem::change_extension(fileName, ".f0").string();
  std::string pmk =
      boost::filesystem::change_extension(fileName, ".pmk").string();

  record.f0Track.readFromFile(f0);
  record.pmkTrack.readFromFile(pmk);

  SF_INFO info = {0};
  SNDFILE* sf = sf_open(fileName.c_str(), SFM_READ, &info);
  if (sf == nullptr) return false;
  record.input_data = new float[info.frames];
  record.input_data_length = info.frames;
  assert(info.channels == 1);
  samplerate = info.samplerate;
  sf_read_float(sf, record.input_data, info.frames);
  sf_close(sf);
  return true;
}
#endif

void VoiceSampler::hanningWindow(float* signal, int size) {
  // see https://github.com/numediart/MBROLA/blob/master/Engine/mbrola.c for
  // reference
  for (int i = 0; i < size; i++)
    signal[i] *= (0.5 * (1.0 - cos((double)i * 2 * M_PI / (float)size)));
}
